﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;

namespace Tingjian.gas.service.Utility.CommonUtility
{
    public static class StringUtility
    {
        public static int StringDateCompare(this string date1, string date2)
        {
            DateTime.TryParse(date1, out DateTime d1);
            DateTime.TryParse(date2, out DateTime d2);
            return DateTime.Compare(d1, d2);
        }

        #region 字符串脱敏
        /// <summary>
        /// 手机号脱敏
        /// </summary>
        /// <param name="mobile"></param>
        /// <returns>返回格式：137****5678</returns>
        public static string DesensitizeMobile(this string mobile)
        {
            return DesensitizeString(mobile, pre: 3, tail: 4);
        }

        /// <summary>
        /// userLoginName脱敏
        /// </summary>
        /// <param name="userLoginName"></param>
        /// <returns>返回格式：yl1********50</returns>
        public static string DesensitizeUserLoginName(this string userLoginName)
        {
            return DesensitizeString(userLoginName, pre: 3, tail: 2);
        }


        /// <summary>
        /// 身份证号脱敏
        /// </summary>
        /// <param name="idCard"></param>
        /// <returns>返回格式：1****************9</returns>
        public static string DesensitizeIdCard(this string idCard)
        {
            return DesensitizeString(idCard, pre: 1, tail: 1);
        }

        /// <summary>
        /// QQ脱敏
        /// </summary>
        /// <param name="qq"></param>
        /// <returns>返回格式：12****89</returns>
        public static string DesensitizeQq(this string qq)
        {
            return DesensitizeString(qq, pre: 2, tail: 2);
        }

        /// <summary>
        /// 微信脱敏
        /// </summary>
        /// <param name="wechat"></param>
        /// <returns>返回格式：12****89</returns>
        public static string DesensitizeWechat(this string wechat)
        {
            return DesensitizeString(wechat, pre: 2, tail: 2);
        }

        /// <summary>
        /// 字符串全脱敏
        /// </summary>
        /// <param name="str"></param>
        /// <returns>返回格式：******</returns>
        public static string DesensitizeStrAll(this string str)
        {
            return DesensitizeString(str, pre: 0, tail: 0);
        }

        /// <summary>
        /// 字符串部分脱敏
        /// </summary>
        /// <param name="str">字符串</param>
        /// <param name="pri">头部字符串长度</param>
        /// <param name="tail">尾部字符串长度</param>
        /// <returns>返回格式：pre位+****+tail位</returns>
        public static string DesensitizeString(this string str, int pre = 0, int tail = 0)
        {
            var ret = string.Empty;
            try
            {
                if (!string.IsNullOrWhiteSpace(str))
                {
                    if (pre < 0 ||
                        tail < 0 ||
                        pre >= str.Length ||
                        tail >= str.Length ||
                        pre + tail >= str.Length)
                    {
                        return "********";
                    }

                    var preStr = pre <= 0 ? string.Empty : str.Substring(0, pre);
                    var tailStr = tail <= 0 ? string.Empty : str.Substring(str.Length - tail);

                    var star = new string('*', str.Length - pre - tail);
                    //var star = string.Concat(Enumerable.Repeat("*", str.Length - pre - tail));

                    ret = $"{preStr}{star}{tailStr}";
                }
            }
            catch
            {
                ret = "******";
            }
            return ret;
        }

        public static string DesensitizationMobile(this string mobile)
        {
            var ret = string.Empty;
            if (!string.IsNullOrWhiteSpace(mobile))
            {
                if (mobile.Length != 11)
                {
                    ret = "-";
                }
                else
                {
                    ret = $"{mobile.Substring(0, 3)}****{mobile.Substring(7)}";
                }
            }

            return ret;
        }

        #endregion

        public static bool IsBase64String(this string s)
        {
            s = s.Trim();
            return (s.Length % 4 == 0) && Regex.IsMatch(s, @"^[a-zA-Z0-9\+/]*={0,3}$", RegexOptions.None);
        }

        public static string RemoveChar(this string s)
        {
            if (s.IsNullOrWhiteSpace()) return "";

            s = Regex.Replace(s, @"\s", "");
            s = Regex.Replace(s, @"\n", "");
            s = Regex.Replace(s, @"\r", "");
            s = Regex.Replace(s, @"\\", "");
            s = Regex.Replace(s, @"/", "");
            return s;
        }

        public static bool IsNullOrWhiteSpace(this string str)
        {
            return string.IsNullOrWhiteSpace(str);
        }


        public static bool HasValue(this string str)
        {
            return !string.IsNullOrWhiteSpace(str);
        }

        public static bool HasValue(this Guid str)
        {
            return str != Guid.Empty;
        }


        public static bool HasValue(this List<string> strList)
        {
            return strList != null && strList.Any();
        }


        public static bool HasValue(this DateTime? time)
        {
            return time != null && time.HasValue;
        }

        public static bool HasValue(this bool? isBool)
        {
            return isBool != null && isBool.HasValue;
        }


        static Regex reg = new Regex("\\d+", RegexOptions.Compiled | RegexOptions.Multiline);
        /// <summary>
        /// list String 转化为 list Long 类型
        /// </summary>
        /// <param name="listString"></param>
        /// <returns></returns>
        public static List<long> ListS2L(this List<string> listString)
        {
            if (listString == null) return new List<long>();

            var listlong = new List<long>();
            listString.ForEach(x =>
            {
                if (reg.IsMatch(x))
                    listlong.Add(Convert.ToInt64(x));
                else
                    throw new Exception("数组中有非法数字");
            });
            return listlong;
        }

        /// <summary>
        /// 从一组连续的数据区间范围内，随机抽取不重复的指定个数的数据
        /// </summary>
        /// <param name="pInMinNumber"></param>
        /// <param name="pInMaxNumber"></param>
        /// <param name="pInNeedsCount"></param>
        /// <param name="pOutArrayIdList"></param>
        /// <param name="pOutMsg"></param>
        /// <returns></returns>
        public static bool GetSiphonNumbers(int pInMinNumber, int pInMaxNumber, int pInNeedsCount, ref int[] pOutArrayIdList, ref string pOutMsg)
        {
            int total = pInMaxNumber - pInMinNumber + 1;
            int[] sequence = new int[total];
            int strMinValue = pInMinNumber;
            int strMaxValue = pInMaxNumber;
            int strArrayCount = pOutArrayIdList.Length;
            if (total <= 0)
            {
                pOutMsg = "抽最数据个数不能小于0";
                return false;
            }
            if (strMinValue > strMaxValue)
            {
                pOutMsg = "InMinNumber 不能大于 InMaxNumber";
                return false;
            }
            if (pInNeedsCount > total || pInNeedsCount <= 0)
            {
                pInNeedsCount = total;
            }
            if (strArrayCount < pInNeedsCount)
            {
                pOutMsg = "输出数组长度不足";
                return false;
            }
            //生成筛选数据
            for (int i = 0; i < total; i++)
            {
                sequence[i] = strMinValue;
                strMinValue++;
            }
            Random random = new Random(GetRandomSeed());
            //数组中最后一个数的下标
            int end = total - 1;
            //抽数pCount个数
            for (int i = 0; i < pInNeedsCount; i++)
            {
                //产生抽取随机数的下标
                int num = random.Next(0, end + 1);
                //保存抽取到的数
                pOutArrayIdList[i] = sequence[num];
                sequence[num] = sequence[end];
                end--;
            }
            return true;
        }

        private static int GetRandomSeed()
        {
            byte[] bytes = new byte[4];
            System.Security.Cryptography.RNGCryptoServiceProvider rng = new System.Security.Cryptography.RNGCryptoServiceProvider();
            rng.GetBytes(bytes);
            return BitConverter.ToInt32(bytes, 0);
        }

        /// <summary>
        /// 获取一个随机索引
        /// </summary>
        /// <param name="pInMinNumber"></param>
        /// <param name="pInMaxNumber"></param>
        /// <param name="pInNeedsCount"></param>
        /// <param name="getIdx">要获取的索引值</param>
        /// <returns></returns>
        public static int GetRandomIndex(int pInMinNumber, int pInMaxNumber, int pInNeedsCount, int getIdx = 0)
        {
            var message = "";
            var outList = new int[1];
            if (GetSiphonNumbers(pInMinNumber, pInMaxNumber, pInNeedsCount, ref outList, ref message))
            {
                if (getIdx < 0 || getIdx >= outList.Length)
                    getIdx = 0;

                return outList[getIdx];
            }

            return -1;
        }

        #region 是否身份证号

        public static bool IsIdCardNo(this string idcardno)
        {
            if (idcardno.IsNullOrWhiteSpace())
            {
                return false;
            }

            return Regex.IsMatch(idcardno, @"^(^\d{15}$|^\d{18}$|^\d{17}(\d|X|x))$", RegexOptions.IgnoreCase);
        }

        public static bool IsMobile(this string mobile)
        {
            if (mobile.IsNullOrWhiteSpace())
            {
                return false;
            }

            return Regex.IsMatch(mobile, @"^\d{11}$", RegexOptions.IgnoreCase);
        }
        #endregion
    }
}
